package bgu.eliav;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Vector;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.ResponseHandler;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;

import android.app.ProgressDialog;
import android.content.ContentValues;
import android.content.Context;
import android.content.SharedPreferences;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;

public class DatabaseExample {
	public static final String KEY_ROWID = "_id";
	public static final String USER_NAME = "name";
	public static final String USER_ID = "user_id";
	public static final String USER_PHONE = "user_phone";
	public static final String USER_ADDRESS = "user_address";
	public static final String USER_BIRTH = "user_birth";

	private static final String TAG = "DatabaseExample";
	private static final String DATABASE_NAME = "MyDB";
	private static final String DATABASE_TABLE = "contacts";
	private static final int DATABASE_VERSION = 1;

	private static final String DATABASE_CREATE = "create table contacts (_id integer primary key autoincrement, "
			+ "name text not null, user_id text not null, user_phone text not null, user_address text not null, user_birth text not null);";

	private final Context context;
	private DatabaseHelper DBHelper;
	private SQLiteDatabase db;
	private static DatabaseExample instance = null;
	private final static Integer myMutex = new Integer(1);

	private String name = "";
	private String id = "";
	private String phone = "";
	private String address = "";
	private String bdate = "";

	ProgressDialog progressDialog;

	private final Handler handler = new Handler() {
		// when recieve a response close the dialog
		public void handleMessage(Message msg) {
			progressDialog.dismiss();
		}
	};

	private DatabaseExample(Context ctx) {
		this.context = ctx;
		DBHelper = new DatabaseHelper(context);
	}

	public static DatabaseExample getInstance(Context context) {
		if (instance == null) {
			synchronized (myMutex) {
				if (instance == null) {
					instance = new DatabaseExample(context);
				}
			}
		}

		return instance;
	}

	private static class DatabaseHelper extends SQLiteOpenHelper {
		DatabaseHelper(Context context) {
			super(context, DATABASE_NAME, null, DATABASE_VERSION);
		}

		@Override
		public void onCreate(SQLiteDatabase db) {
			try {
				db.execSQL(DATABASE_CREATE);
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}

		@Override
		public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
			Log.w(TAG, "Upgrading database from version" + oldVersion + " to "
					+ newVersion + ", which will destroy all old data");
			db.execSQL("DROP TABLE IF EXISTS contacts");
			onCreate(db);

		}

	}

	// ---opens the database---
	public DatabaseExample open() throws SQLException {
		db = DBHelper.getWritableDatabase();
		return this;
	}

	// ---closes the database---
	public void close() {
		DBHelper.close();
	}

	// ---insert a contact into the database---
	public long insertContact(String name, String id, String email,
			String phone, String birth) {
		ContentValues initialValues = new ContentValues();
		initialValues.put(USER_NAME, name);
		initialValues.put(USER_ID, id);
		initialValues.put(USER_PHONE, phone);
		initialValues.put(USER_ADDRESS, email);
		initialValues.put(USER_BIRTH, birth);
		return db.insert(DATABASE_TABLE, null, initialValues);
	}

	// ---deletes a particular contact---
	public boolean deleteContact(long rowId) {
		return db.delete(DATABASE_TABLE, KEY_ROWID + "=" + rowId, null) > 0;
	}

	// ---retrieves all the contacts---
	public Cursor getAllContacts() {
		return db.query(DATABASE_TABLE, new String[] { KEY_ROWID, USER_NAME,
				USER_ID, USER_PHONE, USER_ADDRESS, USER_BIRTH }, null, null,
				null, null, null);
	}

	// ---retrieves a particular contact---
	public Cursor getContact(long rowId) throws SQLException {
		Cursor mCursor = db.query(true, DATABASE_TABLE, new String[] {
				KEY_ROWID, USER_NAME, USER_ID, USER_PHONE, USER_ADDRESS,
				USER_BIRTH }, KEY_ROWID + "=" + rowId, null, null, null, null,
				null);
		if (mCursor != null) {
			mCursor.moveToFirst();
		}
		return mCursor;
	}

	// ---updates a contact---
	public boolean updateContact(long rowId, String name, String email) {
		ContentValues args = new ContentValues();
		args.put(USER_NAME, name);
		args.put(USER_ID, email);
		args.put(USER_PHONE, email);
		args.put(USER_ADDRESS, email);
		args.put(USER_BIRTH, email);
		return db.update(DATABASE_TABLE, args, KEY_ROWID + "=" + rowId, null) > 0;
	}

	public boolean deleteAllContacts() {

		return db.delete(DATABASE_TABLE, "1", null) > 0;
	}

	public boolean deleteContactByUserId(String userId) {
		boolean bool = true;
		bool = db.delete(DATABASE_TABLE, USER_ID + "=" + "'" + userId + "'",
				null) > 0;
		return bool;
	}

	public Cursor getContactByName(String name) throws SQLException {
		Cursor mCursor = db.query(true, DATABASE_TABLE, new String[] {
				KEY_ROWID, USER_NAME, USER_ID, USER_PHONE, USER_ADDRESS,
				USER_BIRTH }, USER_NAME + "=" + "'" + name + "'", null, null,
				null, null, null);
		if (mCursor != null) {
			mCursor.moveToFirst();
		}
		return mCursor;
	}

	public void newUser(String name, String id, String phone, String address,
			String bdate, Context context) {
		boolean local = true;
		SharedPreferences ref = context.getSharedPreferences("bgu.eliav",
				context.MODE_PRIVATE);
		String data = ref.getString("settings", "");
		if (data.equals("local") || data.equals("")) { // from database
			DatabaseExample db = DatabaseExample.getInstance(context);
			open();
			long idInsert = db.insertContact(name, id, phone, address, bdate);
			close();

		} else {
			performRequest(name, id, phone, address, bdate, context);
		}
	}

	private void performRequest(final String name, final String id,
			final String phone, final String address, final String bdate,
			Context context) {
		// create HTTP response handler to handle the HTTP response
		// the response data is extracted from the HTTP message and then it is
		// wrapped in a message
		// which is passed to the android handler for handling

		this.name = name;
		this.id = id;
		this.phone = phone;
		this.address = address;
		this.bdate = bdate;

		final ResponseHandler<String> responseHandler = new ResponseHandler<String>() {
			public String handleResponse(HttpResponse response) {
				// StatusLine status = response.getStatusLine();
				HttpEntity entity = response.getEntity();
				String result = null;
				try {
					result = inputStreamToString(entity.getContent());
					Message message = new Message();
					handler.sendMessage(message);
				} catch (IOException e) {
					Log.e("Class6", " ", e);
				}
				return result;
			}
		};
		// start the progress dialog
		this.progressDialog = ProgressDialog.show(context, "working . . .",
				"performing HTTP request");

		new Thread() {
			public void run() {
				HttpClient httpclient = new DefaultHttpClient();
				HttpPost httppost = new HttpPost(
						"http://www.menachi.com/mobileSite/ex6postNewUser.php");
				try {
					// Add your data
					List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(
							2);
					nameValuePairs.add(new BasicNameValuePair("name", name));
					nameValuePairs.add(new BasicNameValuePair("id", id));
					nameValuePairs.add(new BasicNameValuePair("phone", phone));
					nameValuePairs.add(new BasicNameValuePair("address",
							address));
					nameValuePairs.add(new BasicNameValuePair("bdate", bdate));
					httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
					// Execute HTTP Post Request
					String response = httpclient.execute(httppost,
							responseHandler);

				} catch (ClientProtocolException e) {
					Log.e("LOGTAG", " ", e);
				} catch (IOException e) {
					Log.e("LOGTAG", " ", e);
				}
			} // end run

		}.start(); // end thread

	}

	public static String inputStreamToString(final InputStream stream)
			throws IOException {
		BufferedReader br = new BufferedReader(new InputStreamReader(stream));
		StringBuilder sb = new StringBuilder();
		String line = null;
		while ((line = br.readLine()) != null) {
			sb.append(line + "\n");
		}
		br.close();
		return sb.toString();
	}

	public List<HashMap<String, String>> getContacts(Context context) {
		List<HashMap<String, String>> strlist = new Vector<HashMap<String, String>>();
		SharedPreferences ref = context.getSharedPreferences("bgu.eliav",
				context.MODE_PRIVATE);
		String data = ref.getString("settings", "");

		if (data.equals("local") || data.equals("")) {
			strlist= getListFromDb();
		} else { // work from web
			strlist= getListFromWeb();

		}
		return strlist;
	}

	private List<HashMap<String, String>> getListFromWeb() {
		List<HashMap<String, String>> strlist = new Vector<HashMap<String, String>>();
		URL url;
		try {
			url = new URL(
					"http://www.menachi.com/mobileSite/ex6readingFromDbXML.php");
			// String document =
			// "<?xml version=\"1.0\" encoding=\"utf-8\"?><users><user><name>Eliav</name><id>1</id><phone>0546701995</phone><address>BGU 37/420</address><bdate>1972</bdate></user><user><name></name><id>2</id><phone>342342</phone><address>ffff</address><bdate>333</bdate></user><user><name>test</name><id>3</id><phone>443</phone><address>asdfasdfasdf</address><bdate>44444</bdate></user><user><name>4</name><id>44</id><phone>wer</phone><address>wer</address><bdate>wer</bdate></user></users>";
			DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
			DocumentBuilder db = dbf.newDocumentBuilder();
			Document doc = db.parse(new InputSource(url.openStream()));
			doc.getDocumentElement().normalize();

			NodeList nodeList = doc.getElementsByTagName("user");

			for (int i = 0; i < nodeList.getLength(); i++) {
				HashMap<String, String> hashmap = new HashMap<String, String>();
				Node node = nodeList.item(i);
				NodeList nodeList2 = node.getChildNodes();
				for (int j = 0; j < nodeList2.getLength(); j++) {
					Node child = nodeList2.item(j);
					if (child.getNodeName().contentEquals("name")) {
						Node tmp = child.getFirstChild();
						String strName = "";
						if (tmp != null)
							strName = child.getFirstChild().getNodeValue();
						hashmap.put("name", strName);
					} else if (child.getNodeName().contentEquals("id")) {
						Node tmp = child.getFirstChild();
						String strId = "";
						if (tmp != null)
							strId = child.getFirstChild().getNodeValue();
						hashmap.put("id", strId);
					}
					else if (child.getNodeName().contentEquals("phone")) {
						Node tmp = child.getFirstChild();
						String strId = "";
						if (tmp != null)
							strId = child.getFirstChild().getNodeValue();
						hashmap.put("phone", strId);
					}
					else if (child.getNodeName().contentEquals("address")) {
						Node tmp = child.getFirstChild();
						String strId = "";
						if (tmp != null)
							strId = child.getFirstChild().getNodeValue();
						hashmap.put("address", strId);
					}
					else if (child.getNodeName().contentEquals("bdate")) {
						Node tmp = child.getFirstChild();
						String strId = "";
						if (tmp != null)
							strId = child.getFirstChild().getNodeValue();
						hashmap.put("bdate", strId);
					}
				}
				strlist.add(hashmap);
			}
			System.out.println("");
		} catch (MalformedURLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (ParserConfigurationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (SAXException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		return strlist;
	}
	
	private List<HashMap<String, String>> getListFromDb() {
		List<HashMap<String, String>> strlist = new Vector<HashMap<String, String>>();
		strlist = new Vector<HashMap<String, String>>();
		HashMap<String, String> hashmap = new HashMap<String, String>();
		open();
		Cursor c = getAllContacts();
		if (c.moveToFirst()) {
			do {
				String name=c.getString(1);
				String userId= c.getString(2);
				String address= c.getString(3);
				String phone= c.getString(4);
				String bdate= c.getString(5);

				
				hashmap.put("name", name);
				hashmap.put("id", userId);
				hashmap.put("phone", phone);
				hashmap.put("address", address);
				hashmap.put("bdate", bdate);
				
				strlist.add(hashmap);
				hashmap = new HashMap<String,String>();
				

			} while (c.moveToNext());
		}
		
		return strlist;
	}

}
